/**
 * Encrypts and decrypts an alleged RC4 hash.
 * @author Mika Palmu
 * @version 1.0
 *
 * Orginal Flash port by: 
 * Gabor Penoff - http://www.fns.hu
 * Email: fns@fns.hu
 * 
 * 对称密钥：RC算法
RC系列算法是大名鼎鼎的RSA三人组设计的密钥长度可变的流加密算法，其中最流行的是RC4算法，RC系列算法可以使用2048位的密钥，该算法的速度可以达到DES加密的10倍左右。
RC4算法的原理是“搅乱”， 它包括初始化算法和伪随机子密码生成算法两大部分，在初始化的过程中，密钥的主要功能是将一个256字节的初始数簇进行随机搅乱，不同的数簇在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列，将得到的子密钥序列和明文进行异或运算（XOR）后，得到密文。
由于RC4算法加密采用的是异或方式，所以，一旦子密钥序列出现了重复，密文就有可能被破解，但是目前还没有发现密钥长度达到128位的RC4有重复的可能性，所以，RC4也是目前最安全的加密算法之一。
 * 
 */


package kgame5.kutil.kencrypt {
import kgame5.kutil.*;

public class RC4 {
	//////////////////////
	public static function Encrypt(Key : String, Data : String) {
		var KeyBytes : Array = new Array(255);
		var CypherBytes : Array = new Array(255);
		
		var i:int=0;
		
		for(i = 0;i < 256; ++i) {
			KeyBytes[i] = Key.charCodeAt(i % Key.length);
			CypherBytes[i] = i;
		}
		T.p("1:");
		T.p("KeyBytes");
		T.p(KeyBytes);
		T.p("CypherBytes");
		T.p(CypherBytes);
		var Jump : Number = 0;
		for(i = 0;i < 256; ++i) {
			Jump = (Jump + CypherBytes[i] + KeyBytes[i]) & 0xFF;
			var Tmp : Number = CypherBytes[i]; 
			// Swap:
			CypherBytes[i] = CypherBytes[Jump];
			CypherBytes[Jump] = Tmp;
		}
		T.p("CypherBytes");
		T.p(CypherBytes);
		i = 0;
		Jump = 0;
		var Result : String = "";
		for(var X:int= 0;X < Data.length; ++X) {
			i = (i + 1) & 0xFF;
			Tmp = CypherBytes[i];
			Jump = (Jump + Tmp) & 0xFF;
			var T2 = (Tmp + CypherBytes[Jump]) & 0xFF;
			T.p(X + "~" + T2);
			CypherBytes[i] = CypherBytes[Jump]; 
			// Swap:
			CypherBytes[Jump] = Tmp;
			var c = Data.charCodeAt(X) ^ CypherBytes[T2];
			Result += String.fromCharCode(c);
		}
		T.p(T2);
		return Result; 
	}
}//end of class
}
//////////////////
/*java 方面的加密算法
 public static String Encrypt(String Key,String Data) {
		  short[] KeyBytes=new short[256];//原因在于他们要0xff着两个要是  short,因为byte只在-128~127之间，这里我们要正的数
		  short[] CypherBytes=new short[256];
		  for(int i=0; i<256; ++i) {
			  KeyBytes[i]=(short)Key.codePointAt(i % Key.length());
			  CypherBytes[i]=(short)i;
		  }
		  T("1:");
		  T("KeyBytes");
		  T2(KeyBytes);
		  T("CypherBytes");
		  T2(CypherBytes);

		  int Jump=0;
		  for(int i=0; i<256; ++i) {
			  Jump=(Jump+CypherBytes[i]+KeyBytes[i]) & 0xFF;
			  short Tmp=CypherBytes[i]; // Swap:
			  CypherBytes[i]=CypherBytes[Jump];
			  CypherBytes[Jump]=Tmp;
		  }
		  T("2:");
		  T("CypherBytes");
		  T2(CypherBytes);
		  int i=0;
		  Jump=0;
		  StringBuffer Result=new StringBuffer();

		  for(int X=0; X < Data.length(); ++X) {
			  i=(i+1) & 0xFF;
			  short Tmp=CypherBytes[i];
			  Jump=(Jump+Tmp) & 0xFF;
			  int T=((Tmp+CypherBytes[Jump]) & 0xFF);
			  T(X+"~"+T);
			  CypherBytes[i]=CypherBytes[Jump]; // Swap:
			  CypherBytes[Jump]=Tmp;
			  char c=(char)(Data.codePointAt(X)^CypherBytes[T]);
			  Result.append(c);
		  }
		  
		  return Result.toString(); 
		}
	  ////////////////////////////////////////////
	 public static void T(String s){
		  System.out.println(s);
	  }
	
	 
	  public static void T2(short[] b){
		  String s="";
		  for(int i=0;i<b.length;i++){
			  s+=b[i]+" ";
		  }
		  T("字符:"+s);
	  }
	  //*/
/////////////////
/*js rc4加密算法
//////////////////
function rc4Encrypt(key, pt) {
	var s:Array = new Array();
	for (var i=0; i<256; i++) {
		s[i] = i;
	}
	var j = 0;
	var x;
	for (i=0; i<256; i++) {
		j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
		x = s[i];
		s[i] = s[j];
		s[j] = x;
	}
	i = 0;
	j = 0;
	var ct = '';
	for (var y=0; y<pt.length; y++) {
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		x = s[i];
		s[i] = s[j];
		s[j] = x;
		ct += String.fromCharCode(pt.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
	}
	return ct;
}
//////////
//*/
/////////////////////
/*原始的as的RC4的加密算法
function RC4(Key, Data) {
     KeyBytes=new Array(255);
  CypherBytes=new Array(255);
  for(i=0; i<256; ++i) {
    KeyBytes[i]=Key.charCodeAt(i % Key.length);
    CypherBytes[i]=i;
  }
  Jump=0;
  for(i=0; i<256; ++i) {
    Jump=(Jump+CypherBytes[i]+KeyBytes[i]) & 0xFF;
    Tmp=CypherBytes[i]; // Swap:
    CypherBytes[i]=CypherBytes[Jump];
    CypherBytes[Jump]=Tmp;
  }
  i=0;
  Jump=0;
  Result="";
  for(X=0; X < Data.length; ++X) {
    i=(i+1) & 0xFF;
    Tmp=CypherBytes[i];
    Jump=(Jump+Tmp) & 0xFF;
    T=(Tmp+CypherBytes[Jump]) & 0xFF;
    CypherBytes[i]=CypherBytes[Jump]; // Swap:
    CypherBytes[Jump]=Tmp;
    Result+=String.fromCharCode(Data.charCodeAt(X)^CypherBytes[T]);
  }
  return Result; 
}
//*/

///////////////////